using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using Model;

namespace BusinessTier
{
    public class Tag : ITag 
    {
        private readonly BinaryFormatter _binaryFormatter;
        private IList<string> TaggedSerializedObejcts { get; set; }
        public virtual Guid Id { get; protected set; }
        public virtual string Name { get; protected set; }

        protected Tag()
        {
            TaggedSerializedObejcts = new List<string>();
            _binaryFormatter = new BinaryFormatter();
        }

        public Tag(string name) :this()
        {
            Name = name;
        }



        public virtual void TagObject(ISerializable objectToTag)
        {
            string serializedObject = SerializeObject(objectToTag);
            TaggedSerializedObejcts.Add(serializedObject);
        }

        private string SerializeObject(ISerializable objectToSerialize)
        {
            var stream = new MemoryStream();
            _binaryFormatter.Serialize(stream,objectToSerialize);
            return ConvertByteArrayToString(stream);
        }

        private static string ConvertByteArrayToString(MemoryStream stream)
        {
            return System.Convert.ToBase64String(stream.ToArray());
        }



        public virtual IEnumerable<object>TaggedObjects
        {           
            get
            {
                var result = new List<object>();
                foreach (string s in TaggedSerializedObejcts)
                {              
                    object deserializedObject = DeserializeString(s);
                    result.Add(deserializedObject);
                }

                return result;
            }
        }

        private object DeserializeString(string stringToDesrialize)
        {
            var stream = new MemoryStream(ConvertStringToByteArray(stringToDesrialize));
            return _binaryFormatter.Deserialize(stream);

        }

        private static byte[] ConvertStringToByteArray(string s)
        {
            return System.Convert.FromBase64String(s);
        }
    }
}